/*********************************************************************************************************
**
**                                   GJB 标准测试集
**
**                               Copyright All Rights Reserved
**
**--------------文件信息--------------------------------------------------------------------------------
**
** 文   件   名: gjb_S0102601AQ_deadlock.c
**
** 文件创建日期: 2021 年 1 月 12 日
**
** 描        述: 构造死锁功能, sylixOS 可通过 tp 命令查看死锁状态
*********************************************************************************************************/
#ifdef SYLIXOS
#define __SYLIXOS_KERNEL
#endif

#include <sched.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
// #include "gjb.h"

sem_t    Csem;
sem_t    Dsem;

static pthread_t       thread_id3;
static pthread_t       thread_id4;
static pthread_attr_t  thread_attr3;
static pthread_attr_t  thread_attr4;

int pthread_delay(int ticks);

void *Fun3_security_1 (void *arg)
{
    int res = -100;
    int nDelaytime = 800;

    printf("Task3 is running\n");

    //获取C二值信号量资源
    res = sem_wait(&Csem);
    if (res == 0) {
        printf("Task3 Get Csem Succesful\n");
    } else {
        printf("Task3 Get Csem Failed\n");
    }

    //延时
    sleep(2);

    //获取D信号量资源
    res = -100;
    res = sem_wait(&Dsem);
    if (res == 0) {
        printf("Task3 Get Dsem Succesful\n");

    } else {
        printf("Task3 Get Dsem Failed\n");
    }

    //延时
    pthread_delay(nDelaytime);          //1000个ticks
    res = -100;
    res = sem_post(&Csem);
    if (res == 0) {
        printf("Task3 Release Csem succesful\n");

    } else {
        printf("Task3 Release Csem Failed\n");
    }

    //延时
    pthread_delay(nDelaytime);          //1000个ticks

    res = -100;
    res = sem_post(&Dsem);
    if (res == 0) {
        printf("Task3 Release Dsem succesful\n");
    } else {
        printf("Task3 Release Dsem Failed\n");
    }

    return NULL;
}

void *Fun4_security_1 (void *arg)
{
    int res = -100;
    int nDelaytime = 1000;      //延时时间

    printf("Task4 is running\n");

    //获取C二值信号量资源
    res = sem_wait(&Dsem);
    if (res == 0) {
        printf("Task4 Get Dsem succesful\n");

    } else {
        printf("Task4 Get Dsem Failed\n");
        goto error;
    }

    //延时
    sleep(2);

    //获取D信号量资源
    res = -100;
    res = sem_wait(&Csem);
    if (res == 0) {
        printf("Task4 Get Csem succesful\n");

    } else {
        printf("Task4 Get Csem Failed\n");
        goto error;
    }

    //延时
    pthread_delay(nDelaytime);      //1000个ticks

    res = -100;
    res = sem_post(&Dsem);
    if (res == 0) {
        printf("Task4 Release Dsem succesful\n");

    } else {
        printf("Task4 Release Dsem Failed\n");
        goto error;
    }

    //延时
    pthread_delay(nDelaytime);      //1000个ticks

    res = -100;
    res = sem_post(&Csem);
    if (res == 0) {
        printf("Task4 Release Csem succesful\n");

    } else {
        printf("Task4 Release Csem Failed\n");
        goto error;
    }

    return NULL;

error:
    return  ((void *)123);
}

//测试入口函数
int Test_S0102101AQ_2 (void)
{
    int status = -100;

    //二值信号量初始化
    sem_init(&Csem, 0, 1);
    sem_init(&Dsem, 0, 1);

    //创建任务
    pthread_attr_init(&thread_attr3);
    pthread_attr_init(&thread_attr4);

    // thread_attr3.stackaddr = NULL;
    // thread_attr3.stacksize = PTHREAD_STACK_MIN * 2;
    // thread_attr3.inheritsched = PTHREAD_EXPLICIT_SCHED;
    // thread_attr3.schedpolicy = SCHED_FIFO;
    // thread_attr3.schedparam.sched_priority = 100;
    // thread_attr3.name = "Task3";

    // thread_attr4.stackaddr = NULL;
    // thread_attr4.stacksize = PTHREAD_STACK_MIN * 2;
    // thread_attr4.inheritsched = PTHREAD_EXPLICIT_SCHED;
    // thread_attr4.schedpolicy = SCHED_FIFO;
    // thread_attr4.schedparam.sched_priority = 100;
    // thread_attr4.name = "Task4";

    status = -100;

    status = pthread_create(&thread_id3, &thread_attr3, Fun3_security_1, NULL);
    if (status == 0) {
        printf("Task3 create succesful\n");

    } else {
        printf("Task3 create Failed\n");
    }

    status = -100;
    status = pthread_create(&thread_id4, &thread_attr4, Fun4_security_1, NULL);
    if (status == 0) {
        printf( "Task4 create succesful\n");

    } else {
        printf( "Task4 create Failed\n");
    }

    pthread_join(thread_id3, NULL);
    pthread_join(thread_id4, NULL);

    return  (0);
}
/**********************************************************************
 * 函数名称： GJB_ENTRY()
 * 功能描述： 用户程序入口
 * 输入参数： 无
 * 输出参数： 无
 * 返 回 值： 无
 * 其它说明： 无
 **************************************************************************/
int main(int argc, char **argv)
{
    int  result;

    result = Test_S0102101AQ_2();           /* security 死锁情况        */
    if (result != 0) {
        return (-1);
    }

    return (0);
}

typedef unsigned long long u64;
typedef	unsigned int 	u32;
#define SYSTEM_TICKS_USEC        1000
#define EMINITED 305
u64 g_pthread_delay_tick = 0;
int is_set_sys_rate = 0;
u32 g_sys_uleep_tick = 0;
int pthread_delay(int ticks)
{
    g_pthread_delay_tick = ticks;
    sched_yield();
    if(is_set_sys_rate)
    {
        return usleep(g_sys_uleep_tick * ticks);
    }
    else
    {
        return usleep(SYSTEM_TICKS_USEC * ticks);
    }
}
